// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: chunhui

#pragma once

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <limits>
#include <vector>

#include "coin2/exchange/interval_feed_enum.pb.h"
#include "cc/appcoin2/support/feed/interval_feed_tool/std.h"

namespace interval_feed {

using namespace coin2::exchange::interval_feed_enum;

class OhlcCalculator {
 public:
  OhlcCalculator() {
    ohlc_data_.resize(OhlcType_ARRAYSIZE, std::numeric_limits<double>::quiet_NaN());
  }

  void Update(double price) {
    double& open = ohlc_data_[OhlcType::OPEN];
    double& close = ohlc_data_[OhlcType::CLOSE];
    double& high = ohlc_data_[OhlcType::HIGH];
    double& low = ohlc_data_[OhlcType::LOW];
    std_.Update(price);
    ohlc_data_[OhlcType::MEAN] = std_.GetMean();

    close = price;
    if (std::isnan(open)) {
      open = price;
    }
    if (std::isnan(high)) {
      high = price;
    } else {
      high = std::max(high, price);
    }

    if (std::isnan(low)) {
      low = price;
    } else {
      low = std::min(low, price);
    }
  }

  double Get(OhlcType type) const { return ohlc_data_[type]; }

 private:
  std::vector<double> ohlc_data_;
  StdCalculator std_;
};

}  // namespace interval_feed
